package com.yongbao.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.yongbao.common.PageInfo;
import com.yongbao.common.domain.BaseEntity;
import com.yongbao.common.utils.AssertUtil;
import com.yongbao.mapper.DishOrderMapper;
import com.yongbao.mapper.DishOrderSubMapper;
import com.yongbao.mapper.UserMapper;
import com.yongbao.model.domain.*;
import com.yongbao.model.dtomapper.DishOrderDtoMapper;
import com.yongbao.model.dtomapper.DishOrderSubDtoMapper;
import com.yongbao.model.dtomapper.UserDtoMapper;
import com.yongbao.model.request.DishOrderSubRequest;
import com.yongbao.model.request.DishOrderSubStatisticsRequest;
import com.yongbao.model.util.DishOrderBookConvert;
import com.yongbao.model.util.DishOrderSubConvert;
import com.yongbao.model.vo.DishOrderBookVO;
import com.yongbao.model.vo.DishOrderSubVO;
import com.yongbao.model.vo.DishOrderVO;
import com.yongbao.model.vo.manual.DishOrderSubAddressStatisticsVO;
import com.yongbao.model.vo.manual.DishOrderSubAreaStatisticsVO;
import com.yongbao.model.vo.manual.DishOrderSubStreetStatisticsVO;
import com.yongbao.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author zhanghong
 */
@Service
public class DishOrderSubServiceImpl extends ServiceImpl<DishOrderSubMapper, DishOrderSubDO> implements DishOrderSubService {
    @Autowired
    private DishOrderSubMapper dishOrderSubMapper;
    @Autowired
    private DishOrderMapper dishOrderMapper;
    @Autowired
    private DishOrderService dishOrderService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DishService dishService;
    @Autowired
    private DishOrderBookService dishOrderBookService;
    @Autowired
    private AreaStreetService areaStreetService;

    @Override
    public DishOrderSubVO getByKey(long id) {
        DishOrderSubVO dishOrderSubVO = DishOrderSubDtoMapper.INSTANCE.do2VO(getById(id));
        return dishOrderSubVO;
    }

    @Override
    public PageInfo<DishOrderSubVO> pageQuery(DishOrderSubRequest request) {
        long count = dishOrderSubMapper.pageCount(request);
        List<DishOrderSubDO> list = dishOrderSubMapper.pageQuery(request, request.getPageSize(), request.fetchOffSet());
        List<DishOrderSubVO> dishOrderSubVOList = DishOrderSubConvert.buildDishOrderSubVoList(list);
        for (DishOrderSubVO item : dishOrderSubVOList) {
            // 查询主订单
            DishOrderDO dishOrderDO = dishOrderMapper.selectDOById(item.getOrderId());
            if (dishOrderDO == null) {
                continue;
            }
            DishOrderVO dishOrderVO = DishOrderDtoMapper.INSTANCE.do2VO(dishOrderDO);
            item.setDishOrder(dishOrderVO);

            // 查询用户信息
            UserDO userDO = userMapper.selectDOById(item.getCreateUser());
            item.setUser(UserDtoMapper.INSTANCE.do2VO(userDO));

            // 查询菜品具体信息
            List<DishOrderBookDO> dishOrderBookList = dishOrderBookService.lambdaQuery()
                    .eq(DishOrderBookDO::getOrderId, item.getOrderId())
                    .eq(DishOrderBookDO::getSubOrderId, item.getId())
                    .eq(BaseEntity::getCreateUser, item.getCreateUser())
                    .list();
            if (CollectionUtils.isNotEmpty(dishOrderBookList)) {
                List<DishOrderBookVO> dishOrderDishVOList = DishOrderBookConvert.buildDishOrderBookVoList(dishOrderBookList);
                for (DishOrderBookVO item2 : dishOrderDishVOList) {
                    DishDO dishDO = dishService.lambdaQuery().eq(BaseEntity::getId, item2.getDishId()).last("limit 1").one();
                    if (dishDO != null) {
                        item2.setDishName(dishDO.getDishName());
                        item2.setDishImg(dishDO.getDishImg());
                    }
                }
                item.setDishOrderBookList(dishOrderDishVOList);
            }

        }
        return new PageInfo(request.getPageNum(), request.getPageSize(), dishOrderSubVOList, count);
    }

    @Override
    public List<DishOrderSubVO> listQuery(DishOrderSubRequest request) {
        List<DishOrderSubDO> list = dishOrderSubMapper.selectDOList(DishOrderSubDtoMapper.INSTANCE.request2DO(request));
        List<DishOrderSubVO> dishOrderSubVOS = DishOrderSubConvert.buildDishOrderSubVoList(list);
        return dishOrderSubVOS;
    }

    @Override
    public Boolean add(DishOrderSubRequest request) {
        save(DishOrderSubDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    public Boolean updateByKey(DishOrderSubRequest request) {
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        saveOrUpdate(DishOrderSubDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    public Boolean delByIds(String ids) {
        dishOrderSubMapper.deleteDOByIds(Convert.toStrArray(ids));
        return true;
    }

    @Override
    public DishOrderSubAreaStatisticsVO areaStatistics(DishOrderSubStatisticsRequest request) {
        AssertUtil.assertNotNull(request.getAreaName(), "区名称不能为空");
        String areaNamePrefix = StrUtil.subPre(request.getAreaName(), 2);
        Long count = 0L;
        List<DishOrderDO> dishOrderDOList = dishOrderService.lambdaQuery().likeRight(DishOrderDO::getAreaName, areaNamePrefix).list();
        for (DishOrderDO dishOrderDO : dishOrderDOList) {
            List<DishOrderSubDO> dishOrderSubDOList = this.lambdaQuery().eq(DishOrderSubDO::getOrderId, dishOrderDO.getId()).list();
            for (DishOrderSubDO dishOrderSubDO : dishOrderSubDOList) {
                List<DishOrderBookDO> list = dishOrderBookService.lambdaQuery().eq(DishOrderBookDO::getOrderId, dishOrderDO.getId()).eq(DishOrderBookDO::getSubOrderId, dishOrderSubDO.getId()).list();
                for (DishOrderBookDO dishOrderBookDO : list) {
                    count = count + dishOrderBookDO.getBookNum();
                }
            }
        }
        DishOrderSubAreaStatisticsVO vo = new DishOrderSubAreaStatisticsVO();
        vo.setAreaId(request.getAreaId());
        vo.setAreaName(areaNamePrefix);
        vo.setAreaNamePrefix(areaNamePrefix);
        vo.setCount(Optional.ofNullable(count).orElse(0L));
        return vo;
    }

    @Override
    public List<DishOrderSubStreetStatisticsVO> streetStatistics(DishOrderSubStatisticsRequest request) {
//        AreaStreetDO area = areaStreetService.lambdaQuery().eq(BaseEntity::getId, request.getAreaId()).one();
//        AssertUtil.assertNotNull(area, "区域不存在");
//        List<AreaStreetDO> streetList = areaStreetService.lambdaQuery().eq(AreaStreetDO::getParentId, area.getId()).list();
        AssertUtil.assertNotNull(request.getAreaName(), "区名称不能为空");

        List<DishOrderDO> dishOrderDOList = dishOrderService.lambdaQuery().eq(DishOrderDO::getAreaName, request.getAreaName()).list();
        if (CollectionUtils.isEmpty(dishOrderDOList)) {
            return Collections.emptyList();
        }

        List<DishOrderSubStreetStatisticsVO> dishOrderSubAreaStatisticsVOS = Lists.newArrayList();
        dishOrderDOList.stream().collect(Collectors.groupingBy(DishOrderDO::getStreetName)).forEach((streetName, streetOrderList) -> {
            if (CollectionUtils.isNotEmpty(streetOrderList)) {
                Long count = 0L;
                for (DishOrderDO dishOrderDO : streetOrderList) {
                    List<DishOrderSubDO> dishOrderSubDOList = this.lambdaQuery().eq(DishOrderSubDO::getOrderId, dishOrderDO.getId()).list();
                    for (DishOrderSubDO dishOrderSubDO : dishOrderSubDOList) {
                        List<DishOrderBookDO> list = dishOrderBookService.lambdaQuery().eq(DishOrderBookDO::getOrderId, dishOrderDO.getId()).eq(DishOrderBookDO::getSubOrderId, dishOrderSubDO.getId()).list();
                        for (DishOrderBookDO dishOrderBookDO : list) {
                            count = count + dishOrderBookDO.getBookNum();
                        }
                    }
                }
                DishOrderSubStreetStatisticsVO vo = new DishOrderSubStreetStatisticsVO();
                vo.setStreetName(streetName);
                vo.setCount(count);
                dishOrderSubAreaStatisticsVOS.add(vo);
            }
        });
        return dishOrderSubAreaStatisticsVOS;
    }

    @Override
    public List<DishOrderSubAddressStatisticsVO> addressStatistics(DishOrderSubStatisticsRequest request) {
        AssertUtil.assertNotNull(request.getAreaName(), "区名称不能为空");
        AssertUtil.assertNotNull(request.getStreetName(), "街道不能为空");

        List<DishOrderDO> dishOrderDOList = dishOrderService.lambdaQuery().eq(DishOrderDO::getAreaName, request.getAreaName()).eq(DishOrderDO::getStreetName, request.getStreetName()).list();
        if (CollectionUtils.isEmpty(dishOrderDOList)) {
            return Collections.emptyList();
        }

        List<DishOrderSubAddressStatisticsVO> result = Lists.newArrayList();
        dishOrderDOList.stream().collect(Collectors.groupingBy(DishOrderDO::getAddress)).forEach((roadName, roadOrderList) -> {
            if (CollectionUtils.isNotEmpty(roadOrderList)) {
                List<Long> orderIdList = roadOrderList.stream().map(BaseEntity::getId).collect(Collectors.toList());
                Long count = 0L;
                for (DishOrderDO dishOrderDO : roadOrderList) {
                    List<DishOrderSubDO> dishOrderSubDOList = this.lambdaQuery().eq(DishOrderSubDO::getOrderId, dishOrderDO.getId()).list();
                    for (DishOrderSubDO dishOrderSubDO : dishOrderSubDOList) {
                        List<DishOrderBookDO> list = dishOrderBookService.lambdaQuery().eq(DishOrderBookDO::getOrderId, dishOrderDO.getId()).eq(DishOrderBookDO::getSubOrderId, dishOrderSubDO.getId()).list();
                        for (DishOrderBookDO dishOrderBookDO : list) {
                            count = count + dishOrderBookDO.getBookNum();
                        }
                    }
                }
                DishOrderSubAddressStatisticsVO item = new DishOrderSubAddressStatisticsVO();
                item.setOrderIdList(orderIdList);
                if (CollectionUtils.isNotEmpty(orderIdList)) {
                    item.setDishOrderVO(dishOrderService.getByKey(orderIdList.get(0)));
                }
                item.setAddressName(roadName);
                item.setCount(count);
                result.add(item);
            }
        });
        return result;
    }
}
